#pragma once
#include<vector>

#define VR_NUMS 64

enum Register {
    //vector register, used for VPE
    //!保证向量寄存器从0开始编号，因为向量寄存器单独开辟一个vector进行存储，详见<register.cpp>
    VR0,
    VR1,
    VR2,
    VR3,
    VR4,
    VR5,
    VR6,
    VR7,
    VR8,
    VR9,
    VR10,
    VR11,
    VR12,
    VR13,
    VR14,
    VR15,
    VR16,
    VR17,
    VR18,
    VR19,
    VR20,
    VR21,
    VR22,
    VR23,
    VR24,
    VR25,
    VR26,
    VR27,
    VR28,
    VR29,
    VR30,
    VR31,
    VR32,
    VR33,
    VR34,
    VR35,
    VR36,
    VR37,
    VR38,
    VR39,
    VR40,
    VR41,
    VR42,
    VR43,
    VR44,
    VR45,
    VR46,
    VR47,
    VR48,
    VR49,
    VR50,
    VR51,
    VR52,
    VR53,
    VR54,
    VR55,
    VR56,
    VR57,
    VR58,
    VR59,
    VR60,
    VR61,
    VR62,
    VR63,

    //scalar register
    REG0,
    REG1,
    REG2,
    REG3,
    REG4,
    REG5,
    REG6,
    REG7,
    REG8,
    REG9,
    REG10,
    REG11,
    REG12,
    REG13,
    REG14,
    REG15,
    REG16,
    REG17,
    REG18,
    REG19,
    REG20,
    REG21,
    REG22,
    REG23,
    REG24,
    REG25,
    REG26,
    REG27,
    REG28,
    REG29,
    REG30,
    REG31,
    REG32,
    REG33,
    REG34,
    REG35,
    REG36,
    REG37,
    REG38,
    REG39,
    REG40,
    REG41,
    REG42,
    REG43,
    REG44,
    REG45,
    REG46,
    REG47,
    REG48,
    REG49,
    REG50,
    REG51,
    REG52,
    REG53,
    REG54,
    REG55,
    REG56,
    REG57,
    REG58,
    REG59,
    REG60,
    REG61,
    REG62,
    REG63, 

    //address register, used for AM/SM memory addressing
    AR0,
    AR1,
    AR2,
    AR3,
    AR4,
    AR5,
    AR6,
    AR7,
    AR8,
    AR9,
    AR10,
    AR11,
    AR12,
    AR13,
    AR14,
    AR15,
    OR0,
    OR1,
    OR2,
    OR3,
    OR4,
    OR5,
    OR6,
    OR7,
    OR8,
    OR9,
    OR10,
    OR11,
    OR12,
    OR13,
    OR14,
    OR15,

    //标向量共享寄存器组
    SVR0,
    SVR1,
    SVR2,
    SVR3,
    SVR4,
    SVR5,
    SVR6,
    SVR7,
    SVR8,
    SVR9,
    SVR10,
    SVR11,
    SVR12,
    SVR13,
    SVR14,
    SVR15,

    //向量单元控制寄存器组
    VST,
    VFCR1,
    VFCR2,
    VFCR3,
    VECR,
    VCR,
    VLR,

    //标量单元控制寄存器组
    SST,
    SFCR1,
    SFCR2,
    SCR,
    SECR,
    IER,
    IFR,
    ICR,
    IRR,
    ISTP,
    EER,
    EFR,
    ECR,
    ERR,
    ESTP,
    CGCR,
    CVCCR
};

class RegisterFile {
public:
    RegisterFile() {
        register_value = new std::vector<uint64_t> (140, 0);
        vec_reg_value = new std::vector<std::vector<uint64_t>*> (64);
        for (int i = 0; i < vec_reg_value->size(); i++) {
            vec_reg_value->at(i) = new std::vector<uint64_t>(16, 0);
        }
    }
    ~RegisterFile() {
        delete register_value;
        for (int i = 0; i < vec_reg_value->size(); i++) {
            delete vec_reg_value->at(i);
        }   
        delete vec_reg_value;
    }
    //标量寄存器操作API，for SPU
    uint64_t get_register_value(int id);

    //向量寄存器操作API，for VPU
    std::vector<uint64_t>* get_vec_register_value(int id);

    //标量寄存器操作API，for SPU
    bool set_register_value(int id, uint64_t value);

    //对于VR向量寄存器采用该重载函数，传入16个64位值存储
    //向量寄存器操作API，for VPU
    bool set_register_value(int id, std::vector<uint64_t> *res);

    //对于VR向量寄存器中的单个寄存器进行写入，传入1个64位值存储，index为0～15的VPE ID
    bool set_vec_regsiter_single(int id, int index, uint64_t value);

private:
    //TODO:每一个寄存器内部的64位值，应该使用何种数据类型来存储比较合适？
    //标量寄存器堆，用于SPU
    std::vector<uint64_t>* register_value;
    //向量寄存器堆，用于VPU
    std::vector<std::vector<uint64_t>*>* vec_reg_value;
};

